.text
.section .rodata
.align 8
.LC0:
    .string "Enter a number (empty line to quit):"
.LC1:
    .string "base 10 input, base 10 output: %ld, stopped at %s(% d)\n "
.LC2:
    .string "base 16 input, base 10 output: %ld, stopped at %s(% d)\n "
.LC3:
    .string "Next number:"
.LC4:
    .string "Bye!"

.text
.globl main
.type main, @function
main:
    addi sp, sp, -64
    sd ra, 56(sp)
    sd s0, 48(sp)
    addi s0, sp, 48

    // 分配一下局部变量
    // number: -30(s0)
    // end: -38(s0)
    // value: -42(s0)
    lui a5, %hi(.LC0)
    addi a0, a5, %lo(.LC0)
    call puts

    j .WHILE_12_COMPARE
.WHILE_12_ENTER:
    addi a0, s0, -30
    addi a1, s0, -38
    li a2, 10 /* 10进制 */
    call strtol
    sw a0, -42(s0) /* value */
    lw a1, -42(s0) /* value */
    ld a2, -38(s0)
    lb a3, 0(a2)
    sext.b a3, a3
    lui a5, %hi(.LC1)
    addi a0, a5, %lo(.LC1)
    call printf

    addi a0, s0, -30
    addi a1, s0, -38
    li a2, 16 /* 16进制 */
    call strtol
    sw a0, -42(s0) /* value */
    lw a1, -42(s0) /* value */
    ld a2, -38(s0)
    lb a3, 0(a2)
    sext.b a3, a3
    lui a5, %hi(.LC2)
    addi a0, a5, %lo(.LC2)
    call printf

    lui a5, %hi(.LC3)
    addi a0, a5, %lo(.LC3)
    call puts
.WHILE_12_INCR:
    // 此处不需要做什么
.WHILE_12_COMPARE:
    addi a0, s0, -30
    li a1, 30 /* LIM */
    call s_gets
    beq a0, zero, .WHILE_12_END
    lb a5, -30(s0)
    sext.b a5, a5
    beq a5, zero, .WHILE_12_END
    j .WHILE_12_ENTER
.WHILE_12_END:

    lui a5, %hi(.LC4)
    addi a0, a5, %lo(.LC4)
    call puts

    mv a0, zero
    ld ra, 56(sp)
    ld s0, 48(sp)
    addi sp, sp, 64
    jr ra

.globl s_gets
.type s_gets, @function
s_gets:
    addi sp, sp, -48
    sd ra, 40(sp)
    sd s0, 32(sp)
    addi s0, sp, 32

    // 根据x86的经验，就不存参数了，按照通用的规矩是要存的
    // ret_val: -8(s0)
    // i: -12(s0)

    // 不行，不存参数是不行的，因为调用fgets后，返回值会把a0覆盖了。
    // st:-20(s0)
    // n: -24(s0)
    sd a0, -20(s0) /* st */
    sw a1, -24(s0) /* n */
    sw zero, -12(s0) /* i */

    // 以下两行实际不需要，不过协助这里，万一中间插了代码把a0和a1覆盖了呢
    ld a0, -20(s0) /* st */
    lw a1, -24(s0) /* n */
    lui a5, %hi(stdin)
    ld a2, %lo(stdin)(a5)
    call fgets

    sd a0, -8(s0) /* ret_val */
    beq a0, zero, .EXIT

    j .WHILE_15_COMPARE
.WHILE_15_ENTER:
    lw a5, -12(s0) /* i */
    addiw a5, a5, 1
    sw a5, -12(s0) /* i */
.WHILE_15_COMPARE:
    lw a5, -12(s0) /* i */
    sext.w a5, a5
    ld a4, -20(s0) /* st */
    add a5, a4, a5
    lbu a5, (a5)
    li a4, 10
    beq a5, a4, .IF_17
    bne a5, zero, .WHILE_15_ENTER
.IF_17:
    lw a5, -12(s0) /* i */
    sext.w a5, a5
    ld a4, -20(s0) /* st */
    add a5, a4, a5
    lbu a6, (a5)
    li a4, 10
    bne a6, a4, .WHILE_20_ENTER
    sb zero, (a5)
    j .EXIT
.WHILE_20_ENTER:
    call getchar
    li a5, 10
    bne a0, a5, .WHILE_20_ENTER
.EXIT:
    ld a0, -8(s0) /* ret_val */
    ld ra, 40(sp)
    ld s0, 32(sp)
    addi sp, sp, 48
    jr ra